﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Linq.Expressions;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 简单熟悉winform控件
{
    public partial class Form2 : Form
    {
        //int x = 50, y = 20;
        const int SIZE = 30;
        LinkedList<SnackBody> snake = new LinkedList<SnackBody>();
        SnackBody food = new SnackBody();
        int direction = 1; //1.up, 2.down, 3.left, 4.right
        int score = 0;
        public static int bf = 1;
        int maxScore = 0;
        private bool gameStarted = false;
        public Form2()
        {
            InitializeComponent();

            this.DoubleBuffered = true; //启用双缓冲
            initSnack();
            newFood();
            timer2.Start();

        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0014) // 禁掉清除背景消息
                return;
            base.WndProc(ref m);
        }
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams cp = base.CreateParams;
                cp.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
                return cp;
            }
        }

        void initSnack()
        {
            SnackBody head = new SnackBody();
            head.X = 10 * (SIZE + 1) + 1;
            head.Y = 10 * (SIZE + 1) + 1;

            snake.AddLast(head);
            for (int i = 1; i <= 3; i++)
            {
                SnackBody body = new SnackBody();
                body.X = head.X - i * (SIZE + 1);
                body.Y = head.Y;
                snake.AddLast(body);
            }
        }

        bool IsGameOver()
        {
            SnackBody head = snake.First();
            if (head.X < 0 || head.Y < 0 || head.X >= 775 || head.Y >= 775)
            {
                GameOverLogic();
                return true;
            }
            snake.RemoveFirst();
            foreach (SnackBody body in snake)
            {
                if (body.X == head.X && body.Y == head.Y)
                {
                    GameOverLogic();
                    return true;
                }

            }
            snake.AddFirst(head);
            return false;
        }

        void GameOverLogic()
        {
            timer1.Stop();
            MessageBox.Show("你怎么连贪吃蛇这种小游戏都不会玩啊");
            snake.Clear();
            initSnack();
            maxScore = Math.Max(maxScore, score);
            label2.Text = "最高分数: " + maxScore;
            score = 0;
            direction = 1;
            label3.Text = "当前方向: 右";
            this.Refresh();
        }
        void snakeMove()
        {
            switch (direction)
            {
                //朝下x不变y加
                case 2:
                    SnackBody sb2 = new SnackBody();
                    sb2.X = snake.First().X;
                    sb2.Y = snake.First().Y + (SIZE + 1);
                    snake.AddFirst(sb2);
                    snake.RemoveLast();
                    break;
                //向左y不变x减
                case 3:
                    SnackBody sb3 = new SnackBody();
                    sb3.X = snake.First().X - (SIZE + 1);
                    sb3.Y = snake.First().Y;
                    snake.AddFirst(sb3);
                    snake.RemoveLast();
                    break;
                //向右y不变x加
                case 4:
                    SnackBody sb4 = new SnackBody();
                    sb4.X = snake.First().X + SIZE + 1;
                    sb4.Y = snake.First().Y;
                    snake.AddFirst(sb4);
                    snake.RemoveLast();
                    break;
                //向上x不变y减
                case 1:
                    SnackBody sb1 = new SnackBody();
                    sb1.X = snake.First().X;
                    sb1.Y = snake.First().Y - (SIZE + 1);
                    snake.AddFirst(sb1);
                    snake.RemoveLast();
                    break;
            }
        }

        private void Form2_Paint(object sender, PaintEventArgs e)
        {
        }

        public bool isGrow()
        {
            //分数的成长确认
            if (snake.First<SnackBody>().X == food.X && snake.First<SnackBody>().Y == food.Y)
            {
                snake.AddLast(food);
                snakeMove();

                score += 1 * bf;
                label1.Text = "当前分数: " + score;
                newFood();
                return true;
            }
            else
            {
                return false;
            }


        }

        //定时器，不停地确保蛇的移动
        private void timer1_Tick(object sender, EventArgs e)
        {
            if (gameStarted)
            {
                snakeMove();
                isGrow();
                IsGameOver();
                this.Refresh();

            }
        }

        private void Form2_KeyPress(object sender, KeyPressEventArgs e)
        {
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //开始按钮
            if (!timer1.Enabled)
            {
                gameStarted = true;
                timer1.Start();
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //新游戏
            timer1.Stop();
            DialogResult result = MessageBox.Show("当前分数并不会计入到最高分中,确认开始新游戏吗?", "警告", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
            if (result == DialogResult.OK)
            {
                score = 0;
                newFood();
                snake.Clear();
                initSnack();
                direction = 1;
                label3.Text = "当前方向: 上";
                MessageBox.Show("已重置");
                this.Refresh();
            }
            else
            {
                timer1.Start();
            }
        }

        private void Form2_Load(object sender, EventArgs e)
        {

        }

        private void button3_Click(object sender, EventArgs e)
        {
            //暂停按钮
            timer1.Stop();
        }

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            //画背景
            Pen pen = new Pen(Color.DarkGray);
            for (int i = 0; i < 25; i++)
            {
                g.DrawLine(pen, 0, i * (SIZE + 1), 775, i * (SIZE + 1));
                g.DrawLine(pen, i * (SIZE + 1), 0, i * (SIZE + 1), 775);
            }

            //画蛇和食物
            SolidBrush brush = new SolidBrush(Color.LightPink);
            g.FillRectangle(brush, food.X, food.Y, SIZE, SIZE);
            foreach (SnackBody sb in snake)
            {
                g.FillRectangle(brush, sb.X, sb.Y, SIZE, SIZE);
            }
        }

        public void newFood()
        {
            Random rand = new Random();
            int x = 0;
            int y = 0;
            bool flag = true;
            do
            {
                x = rand.Next(0, 25);
                y = rand.Next(0, 25);
                x = x * (SIZE + 1) + 1;
                y = y * (SIZE + 1) + 1;
                flag = true;
                foreach (SnackBody body in snake)
                {
                    if (body.X == x && body.Y == y)
                    {
                        flag = false;
                        break;
                    }
                }
            } while (!flag);
            food.X = x;
            food.Y = y;
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void Form2_KeyDown(object sender, KeyEventArgs e)
        {


        }

        private void button1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (gameStarted)
            {
                //根据按下的按钮实现更新蛇头的方向
                if (!(direction == 1 && e.KeyChar == 's' || direction == 2 && e.KeyChar == 'w'
                    || direction == 3 && e.KeyChar == 'd' || direction == 4 && e.KeyChar == 'a'))
                {
                    switch (e.KeyChar)
                    {
                        case 'w':
                            direction = 1;
                            label3.Text = "方向: 上";
                            break;
                        case 'a':
                            direction = 3;
                            label3.Text = "方向: 左";
                            break;
                        case 's':
                            direction = 2;
                            label3.Text = "方向: 下";
                            break;
                        case 'd':
                            direction = 4;
                            label3.Text = "方向: 右";
                            break;
                    }
                }
            }
        }

        private void timer2_Tick(object sender, EventArgs e)
        {
            this.Text = "贪吃蛇小游戏" + DateTime.Now.ToString();
        }
    }
}
